package com.springlearn.springsourcecode.chap14;

import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.lang.reflect.UndeclaredThrowableException;

/**
 * @author wtcode
 * @Description
 * @date 2025/4/5 - 15:14
 */
public class Proxy extends Target{

    private MethodInterceptor methodInterceptor;

    public void setMethodInterceptor(MethodInterceptor methodInterceptor) {
        this.methodInterceptor = methodInterceptor;
    }

    static Method save0;
    static Method save1;
    static Method save2;
    static MethodProxy save0Proxy;
    static MethodProxy save1Proxy;
    static MethodProxy save2Proxy;


    static {
        try {
            save0 = Target.class.getMethod("save");
            save1 = Target.class.getMethod("save",int.class);
            save2 = Target.class.getMethod("save",long.class);
            save0Proxy = MethodProxy.create(Target.class,Proxy.class,"()V","save","saveSuper");
            save1Proxy = MethodProxy.create(Target.class,Proxy.class,"(I)V","save","saveSuper");
            save2Proxy = MethodProxy.create(Target.class,Proxy.class,"(J)V","save","saveSuper");

        } catch (NoSuchMethodException e) {
            throw new NoSuchMethodError(e.getMessage());
        }
    }


    // 带原始功能的三个save方法
    public void saveSuper(){
        super.save();
    }

    public void saveSuper(int i){
        super.save(i);
    }

    public void saveSuper(long j){
        super.save(j);
    }


    // 带增强功能的三个save方法
    @Override
    public void save() {
        try {
            methodInterceptor.intercept(this,save0,new Object[0],save0Proxy);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }


    @Override
    public void save(int i) {
        try {
            methodInterceptor.intercept(this,save1, new Object[]{i},save1Proxy);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }

    @Override
    public void save(long j) {
        try {
            methodInterceptor.intercept(this,save2, new Object[]{j},save2Proxy);
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
}
